﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;

using Moe.ECamel.Common.Entities;
using Moe.ECamel.Common.Security;

namespace Moe.ECamel.Server.BL
{
	/// <summary>
	/// Business Logic component for Employees.
	/// </summary>
	public class EmployeeBL : ECamelBL
	{
		/// <summary>
		/// Default constructor for business logic component.
		/// </summary>
		/// <param name="dataContext">Data context to be used by this component's operations.</param>
		public EmployeeBL(ECamelDataContext dataContext)
			: base(dataContext)
		{
		}

		public Employee GetEmployeeById(int employeeId)
		{
			return (from e in dataContext.Employees
					where e.EmployeeId == employeeId
					select e).Single();
		}

		public Employee GetLibraryManager(int libraryId)
		{
			return (from e in dataContext.Employees
			        join ur in dataContext.UserRoles on e.UserId equals ur.UserId
			        where e.LibraryId == libraryId && ur.RoleId == Roles.Manager
			        select e).SingleOrDefault();
		}

		/// <summary>
		/// Gets a list of all the employees in the specified library.
		/// </summary>
		/// <param name="libraryId">Library Id to look for.</param>
		/// <returns>List of employees in specified library.</returns>
		public List<Employee> GetEmployeesByLibrary(int libraryId)
		{
			// Configure load options:
			DataLoadOptions loadOptions = new DataLoadOptions();
			loadOptions.LoadWith<Employee>(e => e.User);
			loadOptions.LoadWith<User>(u => u.UserRoles);
			ECamelDataContext adhocDC = new ECamelDataContext(dataContext.Connection);
			adhocDC.ObjectTrackingEnabled = false;
			adhocDC.LoadOptions = loadOptions;

			List<Employee> employees = (from e in adhocDC.Employees
										where e.LibraryId == libraryId
										select e).ToList();
			return employees;
		}
		/// <summary>
		/// Creates a new emplyee.
		/// </summary>
		/// <param name="employee">Employee details.</param>
		/// <returns>If successful - null, otherwise validation error.</returns>
		public ECamelError CreateEmployee(Employee employee)
		{
			// Validate employee:
			ECamelError validationError = ValidateEmployee(employee);
			if (validationError != null)
				return validationError;

			// Insert:
			dataContext.Employees.InsertOnSubmit(employee);

			return null;
		}
		/// <summary>
		/// Updates an emplyee.
		/// </summary>
		/// <param name="employee">Employee details.</param>
		/// <returns>If successful - null, otherwise validation error.</returns>
		public ECamelError UpdateEmployee(Employee employee)
		{
			// Validate employee:
			ECamelError validationError = ValidateEmployee(employee);
			if (validationError != null)
				return validationError;

			// Update:
			dataContext.Employees.Attach(employee, true);

			return null;
		}

		private ECamelError ValidateEmployee(Employee employee)
		{
			// Validate employee:
			ECamelError error = employee.Validate();
			if (error != null)
				return error;

			return null;
		}

		public IList<Employee> GetAllEmployees()
		{
			return (from e in dataContext.Employees select e).ToList();
		}
	}
}